/*
 * 爱组搭，低代码组件化开发平台
 * ------------------------------------------
 * 受知识产权保护，请勿删除版权申明，开发平台不允许做非法网站，后果自负
 */
package com.aizuda.boot.modules.system.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.aizuda.boot.config.properties.FeiShuConfigProperties;
import com.aizuda.boot.modules.auth.domain.vo.ThirdSysUserVo;
import com.aizuda.boot.modules.common.constant.enums.ResponseCodeEnum;
import com.aizuda.boot.modules.business.contract.util.AuthUtil;
import com.aizuda.boot.modules.system.entity.SysDepartment;
import com.aizuda.boot.modules.system.entity.SysUser;
import com.aizuda.boot.modules.system.entity.SysUserDepartment;
import com.aizuda.boot.modules.system.entity.dto.UserDepartmentDTO;
import com.aizuda.boot.modules.system.entity.vo.DepartmentHeadVO;
import com.aizuda.boot.modules.system.entity.vo.SysDepartmentVO;
import com.aizuda.boot.modules.system.entity.vo.department.*;
import com.aizuda.boot.modules.system.mapper.SysDepartmentMapper;
import com.aizuda.boot.modules.system.mapper.SysUserDepartmentMapper;
import com.aizuda.boot.modules.system.mapper.SysUserMapper;
import com.aizuda.boot.modules.system.service.ISysDepartmentService;
import com.aizuda.boot.modules.system.service.ISysUserDepartmentService;
import com.aizuda.core.api.ApiAssert;
import com.aizuda.service.service.BaseServiceImpl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.lark.oapi.Client;
import com.lark.oapi.service.contact.v3.enums.BatchDepartmentDepartmentIdTypeEnum;
import com.lark.oapi.service.contact.v3.enums.BatchDepartmentUserIdTypeEnum;
import com.lark.oapi.service.contact.v3.model.*;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import me.zhyd.oauth.config.AuthDefaultSource;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import static com.aizuda.boot.modules.common.constant.enums.ResponseCodeEnum.DATA_NOT_FOUND;
import static com.aizuda.boot.modules.common.constant.enums.ResponseCodeEnum.THE_DATA_HAS_BEEN_SET;

/**
 * 部门 服务实现类
 *
 * @author 青苗
 * @since 2021-11-07
 */
@Slf4j
@Service
public class SysDepartmentServiceImpl extends BaseServiceImpl<SysDepartmentMapper, SysDepartment> implements ISysDepartmentService {

    @Resource
    private SysUserMapper sysUserMapper;

    @Resource
    private SysUserDepartmentMapper sysUserDepartmentMapper;

    @Resource
    private ISysUserDepartmentService sysUserDepartmentService;


    @Autowired
    private FeiShuConfigProperties feiShuConfigProperties;

    @Override
    public Page<SysDepartment> page(Page<SysDepartment> page, SysDepartment sysDepartment) {
        LambdaQueryWrapper<SysDepartment> lqw = Wrappers.lambdaQuery(sysDepartment);
        return super.page(page, lqw);
    }

    @Override
    public List<SysDepartmentVO> listTree(SysDepartment sysDepartment) {


        List<SysDepartment> sysDepartmentList = new ArrayList<>();

//        超级管理员能查询所有数据
        if (AuthUtil.isSuperAdmin()) {
            sysDepartmentList = super.list(Wrappers.lambdaQuery(sysDepartment));
        } else {
            //获取当前登录用户所有系统租户对应的部门
            sysDepartmentList = getSysDepartmentListByUserId(AuthUtil.getCurrentUser().getEmployeeId(), sysDepartment);
        }
        //
        if (CollectionUtils.isEmpty(sysDepartmentList)) {
            return null;
        }
        List<Long> departmentIds = sysDepartmentList.stream().map(SysDepartment::getId).toList();

        List<SysDepartment> finalSysDepartmentList = baseMapper.listAllParentDepartments(departmentIds);
        return finalSysDepartmentList.stream().filter(e -> Objects.equals(0L, e.getPid()) || e.getIndependentFlag() == 1).map(e -> {
            SysDepartmentVO vo = e.convert(SysDepartmentVO.class);
            vo.setChildren(this.getChild(vo.getId(), vo.getName(), finalSysDepartmentList));
            return vo;
        }).toList();
    }

    private List<SysDepartment> getSysDepartmentListByUserId(Long userId, SysDepartment sysDepartment) {
        List<Long> depIds = sysUserDepartmentService.listDepartmentIdsByUserId(userId);
        if (CollectionUtils.isEmpty(depIds)) {
            return new ArrayList<>();
        }
        List<String> sysTenantKeys = super.lambdaQuery()
                .in(SysDepartment::getId, depIds)
                .list()
                .stream()
                .map(SysDepartment::getSysTenantKey)
                .distinct()
                .collect(Collectors.toList());

        return super.lambdaQuery(sysDepartment)
                .in(SysDepartment::getSysTenantKey, sysTenantKeys)
                .list();
    }

    /**
     * 获取当前用户所在系统租户的部门列表
     */

    public List<SysDepartment> getSysDepartmentListByUserId(Long userId) {
        List<Long> depIds = sysUserDepartmentService.listDepartmentIdsByUserId(userId);
        List<String> sysTenantKeys = super.lambdaQuery()
                .in(SysDepartment::getId, depIds)
                .list()
                .stream()
                .map(SysDepartment::getSysTenantKey)
                .distinct()
                .collect(Collectors.toList());

        List<SysDepartment> sysDepartmentList = super.lambdaQuery()
                .in(SysDepartment::getSysTenantKey, sysTenantKeys)
                .list();

        return sysDepartmentList;

    }


    /**
     * 获取子节点
     */
    private List<SysDepartmentVO> getChild(Long id, String parentName, List<SysDepartment> sysDepartmentList) {
        // 遍历所有节点，将所有菜单的父id与传过来的根节点的id比较
        List<SysDepartment> childList = sysDepartmentList.stream().filter(e -> Objects.equals(id, e.getPid())).toList();
        if (childList.isEmpty()) {
            // 没有子节点，返回一个空 List（递归退出）
            return null;
        }
        // 递归
        return childList.stream().map(e -> {
            SysDepartmentVO vo = e.convert(SysDepartmentVO.class);
            vo.setParentName(parentName);
            vo.setChildren(this.getChild(vo.getId(), vo.getName(), sysDepartmentList));
            return vo;
        }).toList();
    }

    @Override
    public List<SysDepartment> listAll() {
        return super.list();
    }

    @Override
    public boolean updateById(SysDepartment sysDepartment) {
        ApiAssert.isEmpty(sysDepartment.getId(), "主键不存在无法更新");
        List<Long> ids = baseMapper.selectIdsRecursive(sysDepartment.getId());
        ApiAssert.fail(CollectionUtils.isNotEmpty(ids) && ids.contains(sysDepartment.getPid()), "父分类不能为子分类，请重新选择父分类");
        if (null == sysDepartment.getPid()) {
            // 未设置父ID设置为0
            sysDepartment.setPid(0L);
        }
        return super.updateById(sysDepartment);
    }

    @Override
    public boolean updateStatusById(Long id, Integer status) {
        SysDepartment sysDepartment = new SysDepartment();
        sysDepartment.setId(id);
        sysDepartment.setStatus(Objects.equals(status, 1) ? 1 : 0);
        return super.updateById(sysDepartment);
    }

    @Override
    public Map<Long, String> getAllDepartmentNames() {
        return listAll().stream().collect(Collectors.toMap(SysDepartment::getId, SysDepartment::getName));
    }

    @Override
    public boolean removeByIds(Collection<?> list) {
        this.checkExists(Wrappers.<SysDepartment>lambdaQuery().select(SysDepartment::getId).in(SysDepartment::getPid, list), "存在子类不允许删除");
        return super.removeByIds(list);
    }

    @Override
    public List<DepartmentHeadVO> getDepartmentHeadInfo(Long userId, Integer examineLevel, boolean multiLevel) {
        // 获取用户的主部门
        SysDepartment userMainDept = baseMapper.selectMainDepartmentByUserId(userId);
        if (userMainDept == null) {
            return null;
        }

        List<DepartmentHeadVO> result = new ArrayList<>();

        // 如果是多级审批，获取从当前层级到指定层级的所有主管
        if (multiLevel) {
            for (int level = 1; level <= examineLevel; level++) {
                DepartmentHeadVO headVO = getDepartmentHeadByLevel(userMainDept.getId(), level);
                if (headVO != null) {
                    result.add(headVO);
                }
            }
        } else {
            // 单级审批，只获取指定层级的主管
            DepartmentHeadVO headVO = getDepartmentHeadByLevel(userMainDept.getId(), examineLevel);
            if (headVO != null) {
                result.add(headVO);
            }
        }

        return result.isEmpty() ? null : result;
    }

    /**
     * 根据部门ID和层级获取指定层级的部门主管
     *
     * @param departmentId 用户所在部门ID
     * @param level        层级（1表示直接主管，2表示上级主管，依此类推）
     * @return 部门主管信息
     */
    private DepartmentHeadVO getDepartmentHeadByLevel(Long departmentId, Integer level) {
        if (level == null || level < 1) {
            return null;
        }

        Long currentDeptId = departmentId;

        // 根据层级向上查找对应的部门
        for (int i = 0; i < level; i++) {
            SysDepartment dept = this.getById(currentDeptId);
            if (dept == null) {
                return null;
            }

            if (i == level - 1) {
                // 到达目标层级，返回该部门的主管信息
                if (dept.getHeadId() != null && dept.getHeadName() != null) {
                    DepartmentHeadVO headVO = new DepartmentHeadVO();
                    headVO.setHeadId(dept.getHeadId());
                    headVO.setHeadName(dept.getHeadName());
                    return headVO;
                }
                return null;
            } else {
                // 继续向上查找父部门
                if (dept.getPid() == null || dept.getPid() == 0) {
                    // 已经到达顶级部门，无法继续向上
                    return null;
                }
                currentDeptId = dept.getPid();
            }
        }

        return null;
    }
    // ============ 兼容原department模块的方法实现 ============

    @Override
    public List<DepartmentTreeVO> buildChildren(Long id, List<SysDepartment> list) {
        return list.stream().filter(item -> item.getPid().equals(id) && item.getIndependentFlag() != 1)
                .map(item -> {
                    DepartmentTreeVO departmentTreeVO = convertToDepartmentTreeVO(item);
                    departmentTreeVO.setChildren(buildChildren(item.getId(), list));
                    return departmentTreeVO;
                }).collect(Collectors.toList());
    }

    @Override
    public DepartmentTreeVO getDepartmentTreeBySysTenantKey(String sysTenantKey) {
        List<SysDepartment> list = this.list(Wrappers.<SysDepartment>lambdaQuery()
                .eq(SysDepartment::getSysTenantKey, sysTenantKey));
        if (CollectionUtils.isEmpty(list)) {
            return null;
        }
        List<DepartmentTreeVO> treeList = buildDepartmentTree(list);
        if (CollectionUtils.isEmpty(treeList)) {
            return null;
        }
        return treeList.get(0);
    }

    @Override
    public List<DepartmentTreeVO> getDepartmentTreeByUser() {
        List<SysDepartment> list = new ArrayList<>();
        if (AuthUtil.isSuperAdmin()) {
            // 管理员可以查看所有的部门树形结构
            list = this.list(Wrappers.<SysDepartment>lambdaQuery().eq(SysDepartment::getStatus, 1));
        } else {
            // 获取当前用户可以查看的部门树形结构
            list = this.getSysDepartmentListByUserId(AuthUtil.getCurrentUser().getId());
        }
        if (CollectionUtils.isEmpty(list)) {
            return new ArrayList<>();
        }
        // 保留 list 作为可读变量，不再冗余定义未使用的 finalList

        return buildDepartmentTree(list);
    }

    @Override
    public List<DepartmentTreeVO> listAllParentDepartments(List<Long> departmentIds) {
        List<SysDepartment> sysDepartmentList = baseMapper.listChildDepartments(departmentIds);
        if (CollectionUtils.isEmpty(sysDepartmentList)) {
            return new ArrayList<>();
        }
        return buildChildrenDepartments(sysDepartmentList);

    }

    private List<DepartmentTreeVO> buildChildrenDepartments(List<SysDepartment> sysDepartmentList) {
        if (CollectionUtils.isEmpty(sysDepartmentList)) {
            return new ArrayList<>();
        }

        List<Long> allDepartmentIds = sysDepartmentList.stream().map(SysDepartment::getId).toList();

        // 存放运来构建的顶级
        HashSet<Long> rootIds = new HashSet<>();
        for (SysDepartment dept : sysDepartmentList) {
            if (dept.getPid() != null && (dept.getPid() == 0L || Integer.valueOf(1).equals(dept.getIndependentFlag()))) {
                rootIds.add(dept.getId());
                continue;
            }
            Long currentPid = dept.getPid();
            if (!allDepartmentIds.contains(currentPid)) {
                rootIds.add(dept.getId());
            }

        }
        List<DepartmentTreeVO> collect = sysDepartmentList.stream().filter(item -> rootIds.contains(item.getId())).map(item -> {
            DepartmentTreeVO departmentTreeVO = convertToDepartmentTreeVO(item);
            departmentTreeVO.setChildren(this.buildChildren(item.getId(), sysDepartmentList));
            return departmentTreeVO;
        }).collect(Collectors.toList());
        return collect;
    }

    @Override
    public List<DepartmentTenantDTO> getTenantDepartmentInfoList() {
        return this.list(Wrappers.<SysDepartment>lambdaQuery()
                        .eq(SysDepartment::getPid, 0)
                        .or()
                        .eq(SysDepartment::getIndependentFlag, 1))
                .stream().map(department -> {
                    DepartmentTenantDTO departmentInfoDTO = new DepartmentTenantDTO();
                    departmentInfoDTO.setId(department.getId());
                    departmentInfoDTO.setNodeId(department.getId());
                    departmentInfoDTO.setName(department.getName());
                    departmentInfoDTO.setCode(department.getCode());
                    departmentInfoDTO.setRemark(department.getRemark());
                    departmentInfoDTO.setSort(department.getSort());
                    departmentInfoDTO.setSysTenantKey(department.getSysTenantKey());
                    departmentInfoDTO.setTenantKey(department.getTenantKey());
                    return departmentInfoDTO;
                }).toList();
    }

    @NotNull
    private List<DepartmentTreeVO> buildDepartmentTree(List<SysDepartment> sysDepartmentList) {
        return sysDepartmentList.stream().filter(item -> item.getPid() == 0L || item.getIndependentFlag() == 1).map(item -> {
            DepartmentTreeVO departmentTreeVO = convertToDepartmentTreeVO(item);
            departmentTreeVO.setChildren(this.buildChildren(item.getId(), sysDepartmentList));
            return departmentTreeVO;
        }).collect(Collectors.toList());
    }

    @Override
    public List<DepartmentTreeVO> getDepartmentTreeForCompatibility() {
        List<SysDepartment> list = this.list(Wrappers.<SysDepartment>lambdaQuery().eq(SysDepartment::getStatus, 1));
        if (CollectionUtils.isEmpty(list)) {
            return new ArrayList<>();
        }
        // 获取所有可用的部门
//        List<SysDepartment> allDepartments = this.list(new LambdaQueryWrapper<SysDepartment>().eq(SysDepartment::getDeleted, 0).eq(SysDepartment::getStatus, 1).orderByAsc(SysDepartment::getSort));
        // 保留 list 作为可读变量，不再冗余定义未使用的 finalList


        return buildDepartmentTree(list);


        // 转换为兼容的VO并构建树形结构
//        return buildCompatibleDepartmentTree(list, 0L);
    }

    @Override
    public List<DepartmentTreeVO> getDepartmentTreeByParentIdForCompatibility(Long parentNodeId) {
        List<SysDepartment> departments = baseMapper.selectByPid(parentNodeId);
        List<DepartmentTreeVO> result = new ArrayList<>();

        for (SysDepartment dept : departments) {
            DepartmentTreeVO vo = convertToDepartmentTreeVO(dept);
            vo.setChildren(getDepartmentTreeByParentIdForCompatibility(dept.getId()));
            result.add(vo);
        }

        return result;
    }

    @Override
    public DepartmentDetailVO getDepartmentDetailForCompatibility(Long departmentId) {
        if (departmentId == null) {
            return null;
        }

//        SysDepartment department = this.getById(departmentId);
//        if (department == null || department.getDeleted() == 1) {
//            return null;
//        }
//
        DepartmentDetailVO vo = new DepartmentDetailVO();
//        BeanUtils.copyProperties(department, vo);

        // 构建子部门列表
        vo.setChildren(buildDepartmentDetailChildren(departmentId));

        // 获取部门下的员工信息
        List<EmployeeVO> employees = getDepartmentEmployees(departmentId);
        vo.setEmployees(employees);

        return vo;
    }

    @Override
    public DepartmentInfoDTO getEmployeeMainDepartmentForCompatibility(Long employeeId) {
        // 获取员工的主部门
        SysDepartment mainDepartment = baseMapper.selectMainDepartmentByUserId(employeeId);

        if (mainDepartment == null) {
            return null;
        }

        // 转换为DTO
        DepartmentInfoDTO dto = new DepartmentInfoDTO();
        dto.setId(mainDepartment.getId());
        dto.setNodeId(mainDepartment.getId());
        dto.setNodeParentId(mainDepartment.getPid());
        dto.setName(mainDepartment.getName());
        dto.setCode(mainDepartment.getCode());
        dto.setRemark(mainDepartment.getRemark());
        dto.setSort(mainDepartment.getSort());

        return dto;
    }

    /**
     * 批量获取员工主部门信息
     *
     * @param employeeIds 员工ID列表
     * @return 员工ID到部门信息的映射
     */
    public Map<Long, DepartmentInfoDTO> batchGetEmployeeMainDepartments(List<Long> employeeIds) {
        if (CollectionUtils.isEmpty(employeeIds)) {
            return new HashMap<>();
        }

        // 批量查询用户主部门信息
        List<UserDepartmentDTO> userDepartments = baseMapper.selectMainDepartmentsByUserIds(employeeIds);

        // 转换为Map，key为用户ID，value为部门信息
        Map<Long, DepartmentInfoDTO> result = new HashMap<>();
        for (UserDepartmentDTO userDept : userDepartments) {
            DepartmentInfoDTO dto = new DepartmentInfoDTO();
            dto.setId(userDept.getId());
            dto.setNodeId(userDept.getId());
            dto.setNodeParentId(userDept.getPid());
            dto.setName(userDept.getName());
            dto.setCode(userDept.getCode());
            dto.setRemark(userDept.getRemark());
            dto.setSort(userDept.getSort());

            result.put(userDept.getUserId(), dto);
        }

        return result;
    }

    @Override
    public DepartmentTreeVO getDepartmentTreeByTenantForCompatibility(Long tenantId) {
        SysDepartment tenant = this.getById(tenantId);
        if (tenant == null || tenant.getDeleted() == 1 || tenant.getPid() != 0) {
            return null;
        }

        // 转换租户信息为VO
        DepartmentTreeVO tenantVO = convertToDepartmentTreeVO(tenant);

        // 递归构建整个部门树
        tenantVO.setChildren(buildDepartmentTreeChildren(tenantId));

        return tenantVO;
    }

    /**
     * 构建兼容的部门树
     */
    private List<DepartmentTreeVO> buildCompatibleDepartmentTree(List<SysDepartment> departments, Long parentId) {
        return departments.stream().filter(dept -> parentId.equals(dept.getPid()) && dept.getIndependentFlag() == 0).map(dept -> {
            DepartmentTreeVO vo = convertToDepartmentTreeVO(dept);
            vo.setChildren(buildCompatibleDepartmentTree(departments, dept.getId()));
            return vo;
        }).collect(Collectors.toList());
    }

    /**
     * 转换为DepartmentTreeVO
     */
    private DepartmentTreeVO convertToDepartmentTreeVO(SysDepartment department) {
        DepartmentTreeVO vo = new DepartmentTreeVO();
        vo.setId(department.getId());
        vo.setNodeId(department.getId()); // 使用ID作为nodeId
        vo.setNodeParentId(department.getPid());
        vo.setName(department.getName());
        vo.setCode(department.getCode());
        vo.setRemark(department.getRemark());
        vo.setSort(department.getSort());
        vo.setEnable(department.getStatus());
        return vo;
    }

    /**
     * 构建部门详情的子部门列表
     */
    private List<DepartmentDetailVO> buildDepartmentDetailChildren(Long parentId) {
        List<SysDepartment> children = baseMapper.selectByPid(parentId);

        return children.stream().map(child -> {
            DepartmentDetailVO vo = new DepartmentDetailVO();
            BeanUtils.copyProperties(child, vo);
//            vo.setChildren(buildDepartmentDetailChildren(child.getId()));
            return vo;
        }).collect(Collectors.toList());
    }

    /**
     * 递归构建部门树的子节点
     */
    private List<DepartmentTreeVO> buildDepartmentTreeChildren(Long parentId) {
        List<SysDepartment> children = baseMapper.selectByPid(parentId);

        return children.stream().map(child -> {
            DepartmentTreeVO vo = convertToDepartmentTreeVO(child);
            // 递归构建子部门
            vo.setChildren(buildDepartmentTreeChildren(child.getId()));
            return vo;
        }).collect(Collectors.toList());
    }

    /**
     * 获取部门下的员工信息
     */
    private List<EmployeeVO> getDepartmentEmployees(Long departmentId) {
        // 获取部门下的所有员工ID
        List<Long> userIds = baseMapper.selectUserIdsByDepartmentId(departmentId);

        if (CollectionUtils.isEmpty(userIds)) {
            return new ArrayList<>();
        }

        // 查询员工信息
        List<SysUser> users = sysUserMapper.selectByIds(userIds);

        // 转换为EmployeeVO
        return users.stream().map(user -> {
            EmployeeVO vo = new EmployeeVO();
            vo.setId(user.getId());
            vo.setName(user.getRealName());
            vo.setMobile(user.getPhone());
            vo.setEmail(user.getEmail());
            vo.setAvatar(user.getAvatar());
            vo.setSex("男".equals(user.getSex()) ? 1 : ("女".equals(user.getSex()) ? 0 : -1));
            vo.setWorkStatus(user.getStatus() == 1 ? 1 : 2); // 1:在职, 2:离职

            // 获取该员工的所有部门信息
            List<EmployeeVO.DepartmentVO> departmentVOs = getUserDepartments(user.getId(), departmentId);
            vo.setDepartments(departmentVOs);

            return vo;
        }).collect(Collectors.toList());
    }

    /**
     * 获取员工的部门信息
     */
    private List<EmployeeVO.DepartmentVO> getUserDepartments(Long userId, Long currentDepartmentId) {
        // 查询员工所属的所有部门
        LambdaQueryWrapper<SysUserDepartment> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysUserDepartment::getUserId, userId);
        List<SysUserDepartment> userDepartments = sysUserDepartmentMapper.selectList(wrapper);

        List<EmployeeVO.DepartmentVO> result = new ArrayList<>();
        for (SysUserDepartment ud : userDepartments) {
            SysDepartment dept = this.getById(ud.getDepartmentId());
            if (dept != null && dept.getDeleted() == 0) {
                EmployeeVO.DepartmentVO deptVO = new EmployeeVO.DepartmentVO();
                deptVO.setId(dept.getId());
                deptVO.setName(dept.getName());
                deptVO.setCode(dept.getCode());
                deptVO.setIsMainDepartment(dept.getId().equals(currentDepartmentId));
                deptVO.setIsLeader(false); // TODO: 根据实际业务逻辑设置
                result.add(deptVO);
            }
        }

        return result;
    }


    /**
     * 同步飞书部门
     * 目前仅作为示例，实际同步逻辑需要根据飞书API进行实现
     */
    @Override
    public void syncFeiShuDept() {
        //根据飞书配置文件获取飞书企业信息 创建顶级部门

        log.info("开始同步飞书部门信息...");
        Map<String, FeiShuConfigProperties.FeiShuAppConfig> apps = feiShuConfigProperties.getApps();
        if (CollectionUtil.isEmpty(apps)) {
            log.warn("飞书配置文件中未找到应用信息，无法同步部门");
            return;
        }

        //    顶级企业信息更新
        for (FeiShuConfigProperties.FeiShuAppConfig appConfig : apps.values()) {
            log.info("开始同步机构:{}", appConfig.getName());
            AtomicReference<SysDepartment> sysDepartmentAtomicReference = new AtomicReference<>();
            lambdaQuery().eq(SysDepartment::getTenantKey, appConfig.getTenantKey()).eq(SysDepartment::getPid, 0).oneOpt().ifPresentOrElse(department -> {
                log.info("企业信息已存在，更新顶级部门信息: {}", appConfig.getName());
                // 如果顶级部门已存在，更新信息
                department.setName(appConfig.getName());
                sysDepartmentAtomicReference.set(department);
            }, () -> {
                String sysTenantKey = IdUtil.fastSimpleUUID();
                // 如果顶级部门不存在，创建新部门
                SysDepartment sysDepartment = SysDepartment.builder().name(appConfig.getName()).code(appConfig.getDisplayId()).pid(0L).deleted(0).sort(0).status(1) // 默认启用
                        .tenantKey(appConfig.getTenantKey())
                        .openDepartmentId("0")
                        .sysTenantKey(sysTenantKey)
                        .build();
                sysDepartmentAtomicReference.set(sysDepartment);
            });
            super.saveOrUpdate(sysDepartmentAtomicReference.get());
            log.info("顶级部门信息已同步: {}", sysDepartmentAtomicReference.get().getName());
            //    同步子部门
            try {
                log.info("开始同步部门:{}的子部门信息...", appConfig.getName());
                syncChildDepartments(sysDepartmentAtomicReference.get(), appConfig, null);
            } catch (Exception e) {
                log.error("子同步部门失败，错误信息: {}", e.getMessage(), e);
            }
            log.info("机构:{}, 同步完成", appConfig.getName());
        }

    }


    /**
     * 同步飞书部门主管
     */
    @Override
    public void syncFeiShuDepManager() {
//    1.获取系统中所有飞书关联部门
        Map<String, FeiShuConfigProperties.FeiShuAppConfig> apps = feiShuConfigProperties.getApps();
        if (apps.isEmpty()) {
            log.warn("未配置飞书应用，无法同步用户信息");
            return;
        }
        //一个机构一个机构同步
        log.info("开始同步飞书部门主管信息...");
        apps.values().forEach(appConfig -> {
            // 获取飞书部门列表
            List<SysDepartment> list = super.lambdaQuery()
                    .eq(SysDepartment::getTenantKey, appConfig.getTenantKey())
                    .ne(SysDepartment::getOpenDepartmentId, "0") // 排除顶级部门
                    .list();
            //分组 50个部门一组
            List<List<SysDepartment>> partitionedDepartments = ListUtil.partition(list, 50);
            // 遍历每个组从飞书获取部门主管信息
            partitionedDepartments.forEach(group -> {
                // 构建client
                Client client = Client.newBuilder(appConfig.getAppId(), appConfig.getAppSecret()).logReqAtDebug(true).build();
                try {
                    BatchDepartmentResp resp = client.contact().v3().department().batch(BatchDepartmentReq.newBuilder()
                            .departmentIds(group.stream().map(SysDepartment::getOpenDepartmentId).toArray(String[]::new))
                            .departmentIdType(BatchDepartmentDepartmentIdTypeEnum.OPEN_DEPARTMENT_ID)
                            .userIdType(BatchDepartmentUserIdTypeEnum.UNION_ID)
                            .build());
                    if (resp.getCode() != 0) {
                        log.error("同步部门主管失败,飞书接口报错，错误码: {}, 错误信息: {}", resp.getCode(), resp.getMsg());
                        log.error("详细错误信息:{}", resp.getError());
                        return;
                    }
                    BatchDepartmentRespBody data = resp.getData();
                    if (ObjectUtil.isNull(data) || ObjectUtil.isNull(data.getItems()) || data.getItems().length == 0) {
                        log.info("没有需要同步的部门主管信息");
                        return;
                    }
                    Map<String, Object> departmentIdToManagerIdMap = new HashMap<>();
                    List<String> headerUserIds = new ArrayList<>();
                    Arrays.stream(data.getItems()).forEach(item -> {
                        // 获取部门主管信息
                        if (ObjectUtil.isNull(item.getLeaderUserId())) {
                            log.info("部门 {} 没有主管信息，跳过", item.getName());
                            return;
                        }
                        departmentIdToManagerIdMap.put(item.getOpenDepartmentId(), item.getLeaderUserId());
                        headerUserIds.add(item.getLeaderUserId());
                    });

                    if (CollectionUtil.isEmpty(headerUserIds)) {
                        log.info("当前批次没有需要同步的部门主管信息");
                        return;
                    }


                    //    根据第三方用户uuid获取用户列表
                    List<ThirdSysUserVo> thirdSysUserVoList = sysUserMapper.selectListByThirdUuids(headerUserIds, AuthDefaultSource.FEISHU.getName());
                    if (CollectionUtil.isEmpty(thirdSysUserVoList)) {
                        log.info("没有找到对应的飞书部门主管信息，无法同步部门主管");
                        return;
                    }
                    //    departmentIdToManagerIdMap value替换为用户ID
                    departmentIdToManagerIdMap.entrySet().forEach(entry -> {
                        thirdSysUserVoList.stream()
                                .filter(user -> StrUtil.equals(user.getUuid(), (String) entry.getValue()))
                                .findFirst().ifPresent(entry::setValue);
                    });

                    //    批量更新部门主管信息
                    group.forEach(department -> {
                        ThirdSysUserVo userVo = (ThirdSysUserVo) departmentIdToManagerIdMap.get(department.getOpenDepartmentId());
                        if (ObjectUtil.isNull(userVo)) {
                            log.info("部门 {} 没有主管信息，跳过", department.getName());
                            return;
                        }
                        department.setHeadId(userVo.getId());
                        department.setHeadName(userVo.getRealName());
                    });
                    super.saveOrUpdateBatch(group, 1000);

                } catch (Exception e) {
                    log.error("获取飞书部门主管信息失败，错误信息: {}", e.getMessage(), e);
                    return;
                }

            });

            log.info("同步企业{}下所有部门主管信息完成", appConfig.getName());

        });
    }

    @Override
    public SysDepartment getSysTenantDept(Long userId, Long depId) {

        //获取用户所在部门信息
        SysDepartment sysDepartment = getById(depId);
        //如果部门有独立租户标识
        if (ObjectUtil.isNotEmpty(sysDepartment) && sysDepartment.getIndependentFlag() != 1 && sysDepartment.getPid() != 0) {

            //循环查询上级带有独立租户标识的部门 或者父id=0的顶级部门
            sysDepartment = getHeadSysTenantDept(sysDepartment.getPid());


            //sysDepartment = sysDepartmentService.lambdaQuery()
            //        .eq(SysDepartment::getTenantKey, sysDepartment.getTenantKey())
            //        .and(x -> x.eq(SysDepartment::getPid, 0).or().eq(SysDepartment::getIndependentFlag, 1))
            //        .orderByAsc(SysDepartment::getIndependentFlag)
            //        .last("limit 1")
            //        .one();
        }
        return sysDepartment;
    }

    private SysDepartment getHeadSysTenantDept(Long pid) {
        SysDepartment sysDepartment = super.lambdaQuery()
                .eq(SysDepartment::getId, pid)
                .one();
        if (ObjectUtil.isEmpty(sysDepartment)) {
            log.info("父部门不存在");
            ApiAssert.fail(ResponseCodeEnum.PARAMETER_ERROR);
        }
        if (sysDepartment.getIndependentFlag() == 1 || sysDepartment.getPid() == 0) {
            return sysDepartment;
        }


        return getHeadSysTenantDept(sysDepartment.getPid());
    }

    /**
     * 同步子部门
     * 该方法用于同步飞书中的子部门信息到本地系统
     * 目前仅作为示例，实际同步逻辑需要根据飞书API进行实现
     */
    private void syncChildDepartments(SysDepartment parentDepartment, FeiShuConfigProperties.FeiShuAppConfig appConfig, String pageToken) throws Exception {
        // 构建client
        Client client = Client.newBuilder(appConfig.getAppId(), appConfig.getAppSecret()).logReqAtDebug(true).build();
        ChildrenDepartmentResp children = client.contact().department().children(ChildrenDepartmentReq.newBuilder().departmentId(parentDepartment.getOpenDepartmentId()).pageSize(50).pageToken(pageToken).build());
        if (children.getCode() != 0) {
            log.error("同步部门失败,飞书接口报错，错误码: {}, 错误信息: {}", children.getCode(), children.getMsg());
            log.error("详细错误信息:{}", children.getError());
            throw new RuntimeException("同步部门失败，错误码: " + children.getCode() + ", 错误信息: " + children.getMsg());
        }
        ChildrenDepartmentRespBody data = children.getData();
        if (ObjectUtil.isNull(data) || ObjectUtil.isNull(data.getItems()) || data.getItems().length == 0) {
            log.info("部门 {} 没有子部门", parentDepartment.getName());
            return;
        }

        List<SysDepartment> changeList = new ArrayList<>();
        List<SysDepartment> allList = new ArrayList<>();
        List<SysDepartment> existList = lambdaQuery().in(SysDepartment::getOpenDepartmentId, Arrays.stream(data.getItems()).map(Department::getOpenDepartmentId).collect(Collectors.toList())).list();
        for (Department item : data.getItems()) {
            //    查看部门是否存在
            existList.stream().filter(e -> Objects.equals(e.getOpenDepartmentId(), item.getOpenDepartmentId())).findFirst().ifPresentOrElse(existingDepartment -> {
                allList.add(existingDepartment);
                // 如果部门已存在且部门名称有变化，更新信息
                if (!existingDepartment.getName().equals(item.getName())) {
                    log.info("部门名称已变更，更新部门信息: {}", item.getName());
                    existingDepartment.setName(item.getName());
                    existingDepartment.setSort(Integer.valueOf(item.getOrder()));
                    changeList.add(existingDepartment);
                }
            }, () -> {
                // 如果部门不存在，创建新部门
                SysDepartment newDepartment = SysDepartment.builder().name(item.getName()).code(item.getDepartmentId()).pid(parentDepartment.getId()).deleted(0).sort(0).status(1) // 默认启用
                        .tenantKey(appConfig.getTenantKey())
                        .openDepartmentId(item.getOpenDepartmentId())
                        .sort(Integer.valueOf(item.getOrder()))
                        .sysTenantKey(parentDepartment.getSysTenantKey())
                        .build();
                changeList.add(newDepartment);
                allList.add(newDepartment);
            });

        }
        if (CollectionUtil.isNotEmpty(changeList)) {
            // 批量更新或插入部门信息
            super.saveOrUpdateBatch(changeList, 1000);
            log.info("部门 {} 的子部门信息有变更，数量: {}", parentDepartment.getName(), changeList.size());
        }
        for (SysDepartment sysDepartment : allList) {
            // 递归调用同步子部门
            log.info("开始同步部门:{}的子部门信息...", sysDepartment.getName());
            syncChildDepartments(sysDepartment, appConfig, pageToken);
        }

        //    如果有下一页，重复执行调用
        if (data.getPageToken() != null && data.getHasMore()) {
            log.info("部门 {} 有更多子部门，继续同步...", parentDepartment.getName());
            syncChildDepartments(parentDepartment, appConfig, data.getPageToken());
        } else {
            //    如果没有下一页，结束递归
            log.info("部门 {} 的子部门同步完成", parentDepartment.getName());
        }

    }


    /**
     * 设置独立租户
     *
     * @param departmentId 部门ID
     */
    @Override
    public void setIndependentTenant(Long departmentId) {

        SysDepartment sysDepartment = this.getById(departmentId);
        ApiAssert.fail(ObjectUtil.isEmpty(sysDepartment), DATA_NOT_FOUND);
        // 设置独立租户
        //获取当前及子部门id列表
        List<Long> ids = baseMapper.selectIdsRecursive(departmentId);
        // 检查是否已经是独立租户
        List<SysDepartment> independentDepartments = this.lambdaQuery()
                .in(SysDepartment::getId, ids)
                .eq(SysDepartment::getIndependentFlag, 1)
                .list();
        ApiAssert.fail(CollectionUtil.isNotEmpty(independentDepartments), THE_DATA_HAS_BEEN_SET);
        // 更新子部门的独立租户标识
        //生成独立租户标识 该部门及子部门更新为独立租户标识
        String independentTenantKey = IdUtil.fastSimpleUUID();
        this.lambdaUpdate().in(SysDepartment::getId, ids).set(SysDepartment::getSysTenantKey, independentTenantKey).update();
        log.info("部门及子部门已设置为独立租户，部门ID: {}, 独立租户标识: {}", departmentId, independentTenantKey);
        //    给当前部门设置独立租户标识
        sysDepartment.setSysTenantKey(independentTenantKey);
        sysDepartment.setIndependentFlag(1); // 设置为独立租户标识
        this.updateById(sysDepartment);
    }

    @Override
    public SysDepartment getDepByUserIdAndTenantKey(Long userId, String tenantKey) {
        return sysUserDepartmentMapper.getDepByUserIdAndTenantKey(userId, tenantKey);
    }
}
